using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Windows.Forms;
using System.Xml.XPath;
using System.Xml;
using System.IO;

namespace SimplIDE
{
  public class FileTree : TreeView
  {
    string projectname;
    string dirpath;
    bool loadproject;
    XmlDocument xdoc;
    List<string> filenames;

    public FileTree()
    {
      Dock = DockStyle.Fill;
      filenames = new List<string>();
      projectname = "";
      dirpath = "";
      loadproject = false;
      xdoc = new XmlDocument();
    }

    public void InitFileTree(string dir, string proj)
    {
      TreeNode node;
      projectname = proj;
      dirpath = dir;
      filenames.Add("main.cpp");
      node = this.Nodes.Add(projectname);
      node.Nodes.Add(filenames[0], filenames[0]);
      xdoc.Load(dirpath + @"\ProjectConfig.xml");         
      loadproject = true;
    }

    public void CloseFileTreeContent()
    {
      this.Nodes.Clear();
      projectname = "";
      dirpath = "";
      filenames.Clear();
      loadproject = false;
    }

    public void AddFile(string f)
    {
      filenames.Add(f);
      TreeNode node;
      node = this.Nodes[0];
      node.Nodes.Add(f, f);
      File.WriteAllText(Path.Combine(DirPath, f), "");

      XmlElement childxelem;
      XmlNodeList xnodes;
      xnodes = xdoc.GetElementsByTagName("Project");

      childxelem = xdoc.CreateElement("", "File", "");
      childxelem.SetAttribute("path", dirpath + @"\" + f);
      childxelem.SetAttribute("name", f);
      xnodes[0].AppendChild(childxelem);
      xdoc.Save(dirpath + @"\ProjectConfig.xml");

    }

    public void RemoveFile()
    {
      if (!(this.SelectedNode == this.Nodes[0]) && !(this.SelectedNode == null))
      {
        XmlNode xnode = xdoc.SelectSingleNode("/Directory/Project/File[@name='" + this.SelectedNode.Text + "']");
        xnode.ParentNode.RemoveChild(xnode);
        xdoc.Save(dirpath + @"\ProjectConfig.xml");
        filenames.Remove(this.SelectedNode.Text);
        this.SelectedNode.Remove();

      }
    }

    public void SelectFile(string file)
    {
      TreeNode[] nodes = Nodes.Find(file, true);
      if (nodes == null || nodes.Length == 0)
        return;
      TreeNode node = nodes[0];
      if (node == SelectedNode)
        return;
      SelectedNode = node;
    }

    public void OpenProject(string f, TabControl tb, System.EventHandler evHandler)
    {
      StreamReader sr = new StreamReader(f);
      dirpath = sr.ReadLine();
      projectname = sr.ReadLine();
      sr.Close();
      try
      {
        xdoc.Load(dirpath + @"\ProjectConfig.xml");
      }
      catch (XmlException e)
      {
        MessageBox.Show(e.Message);
      }

      TreeNode node;
      node = this.Nodes.Add(projectname);
      XmlNodeList xlist = xdoc.SelectNodes("/Directory/Project/File[@name]");

      foreach (XmlNode xn in xlist)
      {
        XmlAttributeCollection xattr = xn.Attributes;

        node.Nodes.Add(xattr["name"].Value, xattr["name"].Value);
        filenames.Add(xattr["name"].Value);
      }

      foreach (string str in filenames)
        AddTab(str, tb).TextChanged += evHandler;
      loadproject = true;
    }

    public RichTextBox AddTab(string file, TabControl tabControl)
    {
      CodeEditor editor = new CodeEditor();
      editor.Tag = file;
      string source = Path.Combine(DirPath, file);
      if (File.Exists(source))
        editor.LoadFile(source, RichTextBoxStreamType.PlainText);
      editor.Modified = false;

      TabPage tp = new TabPage();
      tp.Controls.Add(editor);
      tp.Name = file;
      tp.Text = file;
      tabControl.TabPages.Add(tp);
      return editor;
    }

    public void SaveFile(string inp)
    {
      StreamWriter sw = new StreamWriter(dirpath + @"\" + this.SelectedNode.Text);
      sw.Write(inp);
      sw.Close();

    }

    public void SaveAll(TabControl tb)
    {
      foreach (string str in filenames)
      {
        CodeEditor ce = (CodeEditor)tb.Controls[str].Controls[0];
        if (ce.Modified)
        {
          StreamWriter sw = new StreamWriter(dirpath + @"\" + str);
          sw.Write(tb.Controls[str].Controls[0].Text);
          sw.Close();
          ce.Modified = false;
        }
      }
    }

    public bool IsAnyFileModified(TabControl tb)
    {
      foreach (string str in filenames)
      {
        RichTextBox ce = (RichTextBox)tb.Controls[str].Controls[0];
        if (ce.Modified)
          return true;
      }
      return false;
    }

    public bool LoadedProject
    {
      get
      {
        return loadproject;
      }
      set
      {
        loadproject = value;
      }
    }

    public string DirPath
    {
      get
      {
        return dirpath;
      }
      set
      {
        dirpath = value;
      }
    }

      public List<string> FileList
      {
          get
          {
              return filenames;
          }
      }

    private void InitializeComponent()
    {
      this.SuspendLayout();
      // 
      // FileTree
      // 
      this.HideSelection = false;
      this.ResumeLayout(false);

    }
  }
}
